﻿#ifndef _NETPCAP_SYS_DEF_H_
#define _NETPCAP_SYS_DEF_H_

#include <chrono>
#include <cstring>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include <time.h>

#ifdef WIN32
#pragma warning(disable : 4100)
#pragma warning(disable : 4700)
#endif

namespace secsmart_pcap
{
/*网卡信息*/
typedef struct ifinfo {
    std::uint32_t ifindex;
    std::string ifname;
    std::string ifdesc;
} if_info_s, *pif_info_s;

/*抓包数据结构文件头*/
typedef struct pcap_packet {
    struct timeval ts;        /*时间戳 (微秒)*/
    uint32_t frame_len;        /*数据 (以太网帧)长度*/
    uint32_t stream_len;       /*这个包的数据长度*/
    const uint8_t *frame_data; /*数据 (以太网帧)指针*/
    int link_type;             /*链路类型*/
} cap_pkt_t, *pcap_pkt_t;

/*抓包任务状态*/
typedef struct cap_task_info {
    std::string task_name;     /*任务名称*/
    std::string if_name;       /*接口名称*/
    std::string filter_string; /*过滤器字符串*/
    std::string task_thid;     /*任务线程ID*/
    bool is_running = false;   /*任务是否在运行*/
    bool write_file = false;   /*是否写文件*/
    bool read_file = false;    /*是否读文件*/
} cap_task_info_t, *pcap_task_info_t;

/*文件信息*/
typedef struct cap_file_info {
    std::string file_name;     /*写文件名称*/
    std::string dir;           /*抓包文件存放目录*/
    std::uint32_t file_limits; /*写文件限制，读文件数量*/
} cap_file_info_t, *pcap_file_info_t;

/*报文处理函数返回0表示处理成功，否则表示处理失败*/
using fn_pcap_handler = std::function<int(void *pkt, void *ctx)>;
using fn_stop_handler = std::function<void(void *ctx)>;

/*抓包单线程任务*/
typedef struct pcap_task {
    cap_task_info_t task_info;     /*任务基本信息*/
    cap_file_info_t file_info;     /*文件存储信息*/
    fn_pcap_handler fn_pf_handler; /*用户处理函数*/
    fn_stop_handler fn_pf_stoper;  /*用户停止函数*/
    void *fn_ctx;                  /*处理上下文信息*/
} cap_task_t, *pcap_task_t;

/*报文统计*/
typedef struct pcap_pkt_stat {
    uint64_t rx_pkt_nums;
    uint64_t rx_pkt_bytes;
    uint64_t tx_pkt_nums;
    uint64_t tx_pkt_bytes;
    uint64_t rx_pkt_drops;
    uint64_t tx_pkt_drops;
} pcap_pkt_stat_t;

using ifinfo_sptr = std::shared_ptr<if_info_s>;
using captsk_sptr = std::shared_ptr<cap_task_t>;
} // namespace NSNETPCAP

#endif